package com.nulldev.util.dataManagement.preferencesAPI.plist;

import java.io.File;
import java.io.IOException;

import com.nulldev.util.VariableAPI.BooleanUtil;
import com.nulldev.util.data.legacy.XML.lXML;
import com.nulldev.util.data.legacy.XML.lXML.Attr;
import com.nulldev.util.data.legacy.XML.lXML.E;
import com.nulldev.util.data.legacy.XML.lXML.Node;
import com.nulldev.util.dataManagement.preferencesAPI.PreferenceInterface;
import com.nulldev.util.io.file.FileUtil;

public class PreferenceList implements PreferenceInterface<String> {

	private final lXML.E f;
	private final File file;

	public PreferenceList() {
		this.f = new lXML.E("preferences");
		this.file = null;
	}

	public PreferenceList(final lXML.E data) {
		if (data == null)
			throw new NullPointerException("data == null!");
		this.f = new lXML.E("preferences");
		this.file = null;
		data.descendents("option").forEach((d) -> {
			f.add(d);
		});
	}

	public PreferenceList(final File f) {
		if (f == null || !f.exists())
			throw new NullPointerException("f == null!");
		this.f = new lXML.E("preferences");
		this.file = f;
		final lXML.Doc s = lXML.doc(f);
		((E) s.children().get(0)).descendents("option").forEach((d) -> {
			this.f.add(d);
		});
	}

	@Override
	public void close() throws IOException {
	}

	@Override
	public String get(String key) {
		for (final Node element : this.f.children()) {
			if (!(element instanceof E))
				continue;
			final Attr attr = ((E) element).getAttr("key");
			if (attr != null && attr.value().equalsIgnoreCase(key)) {
				return ((E) element).text();
			}
		}
		return null;
	}

	@Override
	public boolean getAsBoolean(String key) {
		return BooleanUtil.safeParse(get(key));
	}

	@Override
	public boolean has(String key) {
		for (final Node element : this.f.children()) {
			if (!(element instanceof E))
				continue;
			final Attr attr = ((E) element).getAttr("key");
			if (attr != null && attr.value().equalsIgnoreCase(key)) {
				return true;
			}
		}
		return false;
	}

	@Override
	public void set(String key, String value) {
		if (has(key)) {
			for (final Node element : this.f.children()) {
				if (!(element instanceof E))
					continue;
				final Attr attr = ((E) element).getAttr("key");
				if (attr != null && attr.value().equalsIgnoreCase(key)) {
					((E) element).setText(value);
					return;
				}
			}
		} else {
			final E e = new E("option", value);
			e.add(new Attr("key", key));
			this.f.add(e);
		}
	}

	@Override
	public void clear() {
		this.f.removeAll();
	}

	@Override
	public void reset() throws IOException {
		this.f.removeAll();
	}

	@Override
	public void sync() {
		if (this.file != null) {
			try {
				FileUtil.writeFile(this.file, this.f.toString());
			} catch (Exception e) {
				throw new RuntimeException(e);
			}
		}
	}

}
